package com.ruoyi.web.controller.erpbase;

import java.util.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.enums.SaleOrPurchType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.flowable.service.IFlowDefinitionService;
import com.ruoyi.flowable.service.IFlowTaskService;
import com.ruoyi.system.domain.FlowProcDefDto;
import com.ruoyi.web.controller.tool.ApprovaUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.flowable.engine.RuntimeService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.Cars;
import com.ruoyi.system.service.ICarsService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.flowable.factory.FlowServiceFactory;
import org.flowable.engine.runtime.ProcessInstance;

/**
 * 车辆Controller
 * 添加swagger需要把在类上@Api("车辆接口")注释加上
 * 在方法上加@ApiOperation("查询车辆列表")
 * @author he
 * @date 2025-08-06
 */
@Api(tags = "车辆接口")
@RestController
@RequestMapping("/system/cars")
public class CarsController extends BaseController
{
    @Autowired
    private ICarsService carsService;

    @Autowired
    private IFlowDefinitionService flowDefinitionService;


    @Autowired
    private IFlowTaskService flowTaskService;


    /**
     * 查询车辆列表
     */
    @ApiOperation("查询车辆列表")
    @PreAuthorize("@ss.hasPermi('system:cars:list')")
    @GetMapping("/list")
    public TableDataInfo list(Cars cars)
    {
        startPage();
        List<Cars> list = carsService.selectCarsList(cars);
        return getDataTable(list);
    }


    @ApiOperation("查询车辆下拉框")
    @PostMapping("/getCarInfoOptions")
    public TableDataInfo getCarInfoOptions(@RequestParam(value = "paramName", required = false) String paramName)
    {
        List<Cars> list = carsService.getCarInfoOptions(paramName);
        return getDataTable(list);
    }

    /**
     * 导出车辆列表
     */
    @ApiOperation("导出车辆")
    @PreAuthorize("@ss.hasPermi('system:cars:export')")
    @Log(title = "车辆", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Cars cars)
    {
        List<Cars> list = carsService.selectCarsList(cars);
        ExcelUtil<Cars> util = new ExcelUtil<Cars>(Cars.class);
        util.exportExcel(response, list, "车辆数据");
    }

    /**
     * 获取车辆详细信息
     */
    @ApiOperation("查询车辆详情")
    @PreAuthorize("@ss.hasPermi('system:cars:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(carsService.selectCarsById(id));
    }

    /**
     * 新增车辆
     */
    @ApiOperation("新增车辆")
    @PreAuthorize("@ss.hasPermi('system:cars:add')")
    @Log(title = "车辆", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Cars cars)
    {
        cars.setCreateUserId(SecurityUtils.getUserId());
        cars.setCreateUserName(SecurityUtils.getUsername());
        cars.setCreateTime(DateUtils.getNowDate());
        return toAjax(carsService.insertCars(cars));
    }

    /**
     * 修改车辆
     */
    @ApiOperation("修改车辆")
    @PreAuthorize("@ss.hasPermi('system:cars:edit')")
    @Log(title = "车辆", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Cars cars)
    {
        cars.setUpdateTime(DateUtils.getNowDate());
        cars.setUpdateUserId(ObjectUtils.isEmpty(SecurityUtils.getUserId()) ? 1 : SecurityUtils.getUserId() );
        cars.setUpdateUserName(ObjectUtils.isEmpty(SecurityUtils.getUsername()) ? "admin" : SecurityUtils.getUsername());
        return toAjax(carsService.updateCars(cars));
    }

    /**
     * 删除车辆
     */
    @ApiOperation("删除车辆")
    @PreAuthorize("@ss.hasPermi('system:cars:remove')")
    @Log(title = "车辆", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(carsService.deleteCarsByIds(ids));
    }


    /**
     * 多辆车辆 批量发起审核
     *
     * 需要在那里配置
     * 1. 画流程图 包括 开始节点 (如何开始,是根据业务代码里调用流程开始方法开始,并将业务变量如 姓名,身份证号等信息传入流程中)
     *      流转线  用户任务(用于审批) 互斥节点(根据变量在其后面的流转线上设置流转条件)
     *      结束节点(结束节点 通过内置或自定义触发器 调用业务代码,实现业务代码的状态改变)com.ruoyi.web.controller.erpbase.ExecListener
     * 2. 配置表单 (表单读取流程中变量数据,展示到表单配置的字段上,需要表单字段名和流程变量名需要一致)
     * 3. 流程保存 , 将表单配置到流程上,
     * 流程改变后,重新保存会新生成新的流程,原流程还存在,并且原流程所绑定的业务流程也存在,如果删除原流程,则原流程所绑定的业务流程也被删除
     */
    @Log(title = "车辆", businessType = BusinessType.UPDATE)
    @PostMapping("/approvalStart")
    public AjaxResult approvalStart(@RequestBody List<Long> ids)
    {
        Cars carsOld = new Cars();
        carsOld.setIds(ids);
        List<Cars> cars1 = carsService.selectCarsList(carsOld);

        if (CollectionUtils.isNotEmpty(cars1)) {

            //根据流程名称 查找流程
            Page<FlowProcDefDto> name = flowDefinitionService.list("司机审核", 1, 10);
            List<FlowProcDefDto> records = name.getRecords();
            FlowProcDefDto flowProcDefDto = records.get(0);

            String deploymentId = flowProcDefDto.getDeploymentId();
            String flowId = flowProcDefDto.getId();
            AjaxResult ajaxResult1 = flowTaskService.flowFormData(deploymentId);

            Map<String, Object> variables = new HashMap<>();
            Object o = ajaxResult1.get("data");
            variables.put("formJson",o);


            List<Long> idsToUpdate = new ArrayList<>();
            for (Cars cars : cars1) {

                variables.put("carId", cars.getId());
                variables.put("licensePlate", cars.getLicensePlate());
                variables.put("driver", cars.getDriver());
                variables.put("carType", cars.getCarType());
                //不需要传递变量,在流程中已经通过表单设置变量名获取
//                variables.put("approvalState2", 2);
//                variables.put("approvalState1", 2);
                AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById(flowId, variables);
                if (ajaxResult.isSuccess()) {
                    idsToUpdate.add(cars.getId());
                }
            }

            if (CollectionUtils.isNotEmpty(idsToUpdate)){
                carsService.updateApprovalState(idsToUpdate, SaleOrPurchType.APPROVAL_YN.getCode());
            }
        }


        return toAjax(1);
    }



    /**
     * 审批流结束触发审核完成
     */
//    @PreAuthorize("@ss.hasPermi('system:cars:remove')")
    @Log(title = "车辆", businessType = BusinessType.UPDATE)
    @PostMapping("/approvalEnd")
    public AjaxResult approvalEnd(@RequestBody Long id)
    {
        carsService.updateApprovalState(Arrays.asList(id),SaleOrPurchType.APPROVAL_YES.getCode());
        return toAjax(1);
    }


    @Log(title = "读取重量")
    @PostMapping("/getWeight")
    public AjaxResult getWeight()
    {
        return success(carsService.getWeight());
    }

}
